home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / liboctave / DiagArray2.h < prev    next >
C/C++ Source or Header  |  1996-03-03  |  5KB  |  248 lines

  1. // Template array classes
  2. /*
  3.  
  4. Copyright (C) 1996 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22. */
  23.  
  24. #if !defined (octave_DiagArray2_h)
  25. #define octave_DiagArray2_h 1
  26.  
  27. #if defined (__GNUG__)
  28. #pragma interface
  29. #endif
  30.  
  31. #include <cassert>
  32. #include <cstdlib>
  33.  
  34. #include "Array2.h"
  35. #include "lo-error.h"
  36.  
  37. class idx_vector;
  38.  
  39. // A two-dimensional array with diagonal elements only.
  40. //
  41. // Idea and example code for Proxy class and functions from:
  42. //
  43. // From: kanze@us-es.sel.de (James Kanze)
  44. // Subject: Re: How to overload [] to do READ/WRITE differently ?
  45. // Message-ID: <KANZE.93Nov29151407@slsvhdt.us-es.sel.de>
  46. // Sender: news@us-es.sel.de
  47. // Date: 29 Nov 1993 14:14:07 GMT
  48. // --
  49. // James Kanze                             email: kanze@us-es.sel.de
  50. // GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
  51.  
  52. template <class T>
  53. class DiagArray2 : public Array<T>
  54. {
  55. private:
  56.  
  57.   T get (int i) { return Array<T>::xelem (i); }
  58.  
  59.   void set (const T& val, int i) { Array<T>::xelem (i) = val; }
  60.  
  61.   class Proxy
  62.   {
  63.   public:
  64.  
  65.     Proxy (DiagArray2<T> *ref, int r, int c)
  66.       : i (r), j (c), object (ref) { } 
  67.  
  68.     const Proxy& operator = (const T& val) const
  69.       {
  70.     if (i == j)
  71.       {
  72.         if (object)
  73.           object->set (val, i);
  74.       }
  75.     else
  76.       (*current_liboctave_error_handler)
  77.         ("invalid assignment to off-diagonal in diagonal array");
  78.  
  79.     return *this;
  80.       }
  81.  
  82.     operator T () const
  83.       {
  84.     if (object && i == j)
  85.       return object->get (i);
  86.     else
  87.       {
  88.         static T foo (0);
  89.         return foo;
  90.       }
  91.       }
  92.  
  93.   private:
  94.  
  95.     // XXX FIXME XXX -- this is declared private to keep the user from
  96.     // taking the address of a Proxy.  Maybe it should be implemented
  97.     // by means of a companion function in the DiagArray2 class.
  98.  
  99.     T *operator& () const { assert (0); return (T *) 0; }
  100.  
  101.     int i;
  102.     int j;
  103.  
  104.     DiagArray2<T> *object;
  105.  
  106.   };
  107.  
  108. friend class Proxy;
  109.  
  110. protected:
  111.  
  112.   int nr;
  113.   int nc;
  114.  
  115.   DiagArray2 (T *d, int r, int c) : Array<T> (d, r < c ? r : c)
  116.     {
  117.       nr = r;
  118.       nc = c;
  119.       set_max_indices (2);
  120.     }
  121.  
  122. public:
  123.  
  124.   DiagArray2 (void) : Array<T> ()
  125.     {
  126.       nr = 0;
  127.       nc = 0;
  128.       set_max_indices (2);
  129.     }
  130.  
  131.   DiagArray2 (int r, int c) : Array<T> (r < c ? r : c)
  132.     {
  133.       nr = r;
  134.       nc = c;
  135.       set_max_indices (2);
  136.     }
  137.  
  138.   DiagArray2 (int r, int c, const T& val) : Array<T> (r < c ? r : c, val)
  139.     {
  140.       nr = r;
  141.       nc = c;
  142.       set_max_indices (2);
  143.     }
  144.  
  145.   DiagArray2 (const Array<T>& a) : Array<T> (a)
  146.     {
  147.       nr = nc = a.length ();
  148.       set_max_indices (2);
  149.     }
  150.  
  151.   DiagArray2 (const DiagArray2<T>& a) : Array<T> (a)
  152.     {
  153.       nr = a.nr;
  154.       nc = a.nc;
  155.       set_max_indices (2);
  156.     }
  157.  
  158.   ~DiagArray2 (void) { }
  159.  
  160.   DiagArray2<T>& operator = (const DiagArray2<T>& a)
  161.     {
  162.       if (this != &a)
  163.     {
  164.       Array<T>::operator = (a);
  165.       nr = a.nr;
  166.       nc = a.nc;
  167.     }
  168.  
  169.       return *this;
  170.     }
  171.  
  172. #if 0
  173.   operator Array2<T> () const
  174.     {
  175.       Array2<T> retval (nr, nc,  T (0));
  176.  
  177.       int len = nr < nc ? nr : nc;
  178.  
  179.       for (int i = 0; i < len; i++)
  180.     retval.xelem (i, i) = xelem (i, i);
  181.  
  182.       return retval;
  183.     }
  184. #endif
  185.  
  186.   int dim1 (void) const { return nr; }
  187.   int dim2 (void) const { return nc; }
  188.  
  189.   int rows (void) const { return nr; }
  190.   int cols (void) const { return nc; }
  191.   int columns (void) const { return nc; }
  192.  
  193. #if 1
  194.   Proxy elem (int r, int c)
  195.     {
  196.       return Proxy (this, r, c);
  197.     }
  198.  
  199.   Proxy checkelem (int r, int c)
  200.     {
  201.       if (r < 0 || c < 0 || r >= nr || c >= nc)
  202.     {
  203.       (*current_liboctave_error_handler) ("range error");
  204.       return Proxy (0, r, c);
  205.     }
  206.       else
  207.     return Proxy (this, r, c);
  208.     }
  209.  
  210.   Proxy operator () (int r, int c)
  211.     {
  212.       if (r < 0 || c < 0 || r >= nr || c >= nc)
  213.     {
  214.       (*current_liboctave_error_handler) ("range error");
  215.       return Proxy (0, r, c);
  216.     }
  217.       else
  218.     return Proxy (this, r, c);
  219.   }
  220. #else
  221.   T& elem (int r, int c);
  222.   T& checkelem (int r, int c);
  223.   T& operator () (int r, int c);
  224. #endif
  225.  
  226.   T elem (int r, int c) const;
  227.   T checkelem (int r, int c) const;
  228.   T operator () (int r, int c) const;
  229.  
  230.   // No checking.
  231.  
  232.   T& xelem (int r, int c);
  233.   T xelem (int r, int c) const;
  234.  
  235.   void resize (int n, int m);
  236.   void resize (int n, int m, const T& val);
  237.  
  238.   void maybe_delete_elements (idx_vector& i, idx_vector& j);
  239. };
  240.  
  241. #endif
  242.  
  243. /*
  244. ;;; Local Variables: ***
  245. ;;; mode: C++ ***
  246. ;;; End: ***
  247. */
  248.